package scatter.schedulequartz.rest.record.service.impl;

import brave.Tracer;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.quartz.JobExecutionContext;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import scatter.common.rest.service.IBaseQueryFormServiceImpl;
import scatter.common.rest.tools.TraceTool;
import scatter.common.rest.validation.DictService;
import scatter.schedulequartz.pojo.form.NameAndGroupForm;
import scatter.schedulequartz.pojo.record.form.SchedulerRecordPageQueryForm;
import scatter.schedulequartz.pojo.record.po.SchedulerRecord;
import scatter.schedulequartz.rest.record.mapper.SchedulerRecordMapper;
import scatter.schedulequartz.rest.record.service.ISchedulerRecordService;

import java.time.LocalDateTime;

/**
 * <p>
 * 任务计划执行记录表 服务实现类
 * </p>
 *
 * @author yw
 * @since 2021-10-11
 */
@Service
@Transactional
public class SchedulerRecordServiceImpl extends IBaseQueryFormServiceImpl<SchedulerRecordMapper, SchedulerRecord , SchedulerRecordPageQueryForm> implements ISchedulerRecordService {

    @Autowired
    private DictService dictService;

    @Override
    public boolean existRunning(NameAndGroupForm nameAndGroupForm) {
        SchedulerRecord schedulerRecord = new SchedulerRecord().setJobName(nameAndGroupForm.getName()).setJobGroup(nameAndGroupForm.getGroup());
        String runningDictId = dictService.getIdByGroupCodeAndValue(SchedulerRecord.SchedulerRecordStatusGroupCode.scheduler_record_status.groupCode(), SchedulerRecord.SchedulerRecordStatusDictItem.running.itemValue());
        schedulerRecord.setStatusDictId(runningDictId);
        return count(Wrappers.query(schedulerRecord)) > 0;
    }

    @Override
    public String addStartJobRecord(JobExecutionContext context) throws SchedulerException {
        SchedulerRecord schedulerRecord = mapRecordByJobExecutionContext(context);

        String runningDictId = dictService.getIdByGroupCodeAndValue(SchedulerRecord.SchedulerRecordStatusGroupCode.scheduler_record_status.groupCode(), SchedulerRecord.SchedulerRecordStatusDictItem.running.itemValue());
        schedulerRecord.setStatusDictId(runningDictId);

        boolean save = save(schedulerRecord);
        return schedulerRecord.getId();
    }

    @Override
    public boolean endJobUpdateRecord(String recordId, String result, String statusDictId) {
        SchedulerRecord schedulerRecord = new SchedulerRecord();

        schedulerRecord.setId(recordId);
        schedulerRecord.setResult(result);
        schedulerRecord.setEndAt(LocalDateTime.now());
        schedulerRecord.setStatusDictId(statusDictId);
        updateById(schedulerRecord);
        return true;
    }

    @Override
    public boolean jobConflictOverRecord(JobExecutionContext context,String result) throws SchedulerException {
        String recordId = addStartJobRecord(context);
        String failDictId = dictService.getIdByGroupCodeAndValue(SchedulerRecord.SchedulerRecordStatusGroupCode.scheduler_record_status.groupCode(), SchedulerRecord.SchedulerRecordStatusDictItem.fail.itemValue());

        boolean b = endJobUpdateRecord(recordId, result, failDictId);
        return b;
    }

    /**
     * 映射实体
     * @param context
     * @return
     * @throws SchedulerException
     */
    private SchedulerRecord mapRecordByJobExecutionContext(JobExecutionContext context) throws SchedulerException {
        SchedulerRecord schedulerRecord = new SchedulerRecord();
        schedulerRecord.setSchedulerName(context.getScheduler().getSchedulerName());
        schedulerRecord.setSchedulerInstanceId(context.getScheduler().getSchedulerInstanceId());
        schedulerRecord.setJobName(context.getJobDetail().getKey().getName());
        schedulerRecord.setJobGroup(context.getJobDetail().getKey().getGroup());
        schedulerRecord.setStartAt(LocalDateTime.now());
        schedulerRecord.setParams(toJsonStr(context.getJobDetail().getJobDataMap()));

        schedulerRecord.setTraceId(TraceTool.getTraceId());

        return schedulerRecord;
    }
}
